package com.mulanweb.validator;

import com.jfinal.kit.PathKit;
import org.apache.commons.validator.*;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by hcy on 2016/4/8.
 */
public class ValidateUtils {

    private static Map<String, ValidatorResources> resourcesCache = new ConcurrentHashMap<String, ValidatorResources>();


    private static URL GLOBAL_RULES_CONFIG = null;

    private static synchronized void initGlobalRulesConfig() {
        GLOBAL_RULES_CONFIG = ValidateUtils.class.getClassLoader().getResource("validator/global-rules.xml");
    }

    private static URL getGlobalRulesConfig() {
        if (null == GLOBAL_RULES_CONFIG) {
            initGlobalRulesConfig();
        }
        return GLOBAL_RULES_CONFIG;
    }


    private static synchronized void loadResources(String resource) {
        File file = new File(PathKit.getRootClassPath() + File.separator + resource.replace("/", File.separator));
        // URL resourceURL = ValidateUtils.class.getClassLoader().getResource(resource);
//        if (null == resourceURL) {
//            return;
//        }
        if (!file.exists()) {
            return;
        }

        URL resourceURL = null;
        try {
            resourceURL = file.toURI().toURL();
        } catch (MalformedURLException e) {
            return ;
        }

        URL[] resourceURLs = new URL[]{getGlobalRulesConfig(), resourceURL};
        try {
            ValidatorResources vr = new ValidatorResources(resourceURLs);
            resourcesCache.put(resource, vr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static ValidatorResources getResources(String resource) {
        if (!resourcesCache.containsKey(resource)) {
            loadResources(resource);
        }
        return resourcesCache.get(resource);
    }


    public static ValidateStatus validate(String resource,
                                          String formName,
                                          Object data) {
        try {
            ValidatorResources resources = getResources(resource);
            if (null == resources) {
                return ValidateStatus.NOT_FOUND_RESOURCE;
            }
            Form form = resources.getForm(Locale.getDefault(), formName);
            if (null == form) {
                return ValidateStatus.NOT_FOUND_FORM;
            }

            Validator validator = new Validator(resources, formName);
            validator.setParameter(Validator.BEAN_PARAM, data);
            ValidatorResults results = validator.validate();

            Set<String> properNames = results.getPropertyNames();
            for (String propName : properNames) {
                ValidatorResult result = results.getValidatorResult(propName);
                Iterator<String> actionIt = result.getActions();
                while (actionIt.hasNext()) {
                    String actionName = actionIt.next();
                    if (!result.isValid(actionName)) {
                        Field field = form.getField(propName);
                        String comment = field.getVarValue("comment");
                        if (null == comment) {
                            comment = propName;
                        }
                        ValidatorAction validatorAction = resources.getValidatorAction(actionName);
                        String message = MessageFormat.format(validatorAction.getMsg(), new Object[]{propName + "[" + comment + "]"});
                        return new ValidateStatus(ValidateStatus.FAILURE.getCode(), message);
                    }
                }
            }
        } catch (ValidatorException e) {
            e.printStackTrace();
            return ValidateStatus.FAILURE;
        }
        return ValidateStatus.SUCCESS;
    }


}
